package com.nuo.backend.modules.security.controller;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nuo.backend.modules.security.annotation.SecMenu;
import com.nuo.backend.modules.security.entity.SecRoleEntity;
import com.nuo.backend.modules.security.entity.SecRoleMenuEntity;
import com.nuo.backend.modules.security.entity.SecUserEntity;
import com.nuo.backend.modules.security.service.SecRoleMenuService;
import com.nuo.backend.modules.security.service.SecUserService;
import com.nuo.backend.modules.shiro.entity.SysMenuEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.nuo.backend.modules.security.entity.SecMenuEntity;
import com.nuo.backend.modules.security.service.SecMenuService;
import com.nuo.backend.common.utils.PageUtils;
import com.nuo.backend.common.utils.R;



/**
 * 菜单管理
 *
 * @author nuo
 * @email 3033616351@qq.com
 * @date 2022-12-04 01:55:55
 */
@RestController
@RequestMapping("sec/menu")
public class SecMenuController {
    @Autowired
    private SecMenuService secMenuService;
    @Autowired
    private SecUserService secUserService;
    @Autowired
    private SecRoleMenuService secRoleMenuService;

    /**
     * 导航菜单
     */
    @GetMapping("/nav")
    public R nav(){
        SecUserEntity secUser = (SecUserEntity) secUserService.getUserBySec().get("user");
        Set<Long> roleIdSet = secUser.getSecRoleList().stream().map(SecRoleEntity::getRoleId).collect(Collectors.toSet());
        // TODO root 获取全部
        if (!roleIdSet.contains(1L)) {
            return R.ok().put("menuList", secMenuService.getUserMenuList(null));
        }
        return R.ok().put("menuList", secMenuService.getUserMenuList(secRoleMenuService.list(new LambdaQueryWrapper<SecRoleMenuEntity>().in(SecRoleMenuEntity::getRoleId, roleIdSet)).stream().map(SecRoleMenuEntity::getMenuId).distinct().collect(Collectors.toList())));
    }

    /**
     * 保存
     */
    @SecMenu
    @RequestMapping("/save")
    public R save(@RequestBody SecMenuEntity sysMenu){
		secMenuService.save(sysMenu);
        return R.ok();
    }

    /**
     * 删除
     */
    @SecMenu
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] menuIds){
        if (menuIds != null && menuIds.length > 0) {
            //判断是否有子菜单或按钮
            List<SecMenuEntity> list = secMenuService.list(new LambdaQueryWrapper<SecMenuEntity>().in(SecMenuEntity::getParentId, Arrays.asList(menuIds)));
            if (!list.isEmpty()) {
                return R.error("请先删除子菜单或按钮");
            } else {
                secMenuService.removeByIds(Arrays.asList(menuIds));
            }
        }
        return R.ok("删除成功...");
    }

    /**
     * 修改
     */
    @SecMenu
    @RequestMapping("/update")
    public R update(@RequestBody SecMenuEntity secMenu){
		secMenuService.updateById(secMenu);
        return R.ok();
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{menuId}")
    public R info(@PathVariable("menuId") Long menuId){
        SecMenuEntity secMenu = secMenuService.getById(menuId);
        return R.ok().put("secMenu", secMenu);
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(){
        List<SecMenuEntity> secMenuList = secMenuService.list();
        // 将id和菜单绑定
        Map<Long, SecMenuEntity> secMenuMap = secMenuList.stream().collect(Collectors.toMap(SecMenuEntity::getMenuId, Function.identity()));

        // 组装菜单的层级关系
        for (int i = 0; i < secMenuList.size();) {
            SecMenuEntity parentMenu = secMenuMap.get(secMenuList.get(i).getParentId());
            if (Objects.nonNull(parentMenu)) {
                parentMenu.getList().add(secMenuList.get(i));
                // 将这个菜单从当前节点移除
                secMenuList.remove(i);
            } else {
                i ++;
            }
        }
        return R.ok().put("secMenuList", secMenuList);
    }

}
